package com.xingda.packing.common;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONException;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.TypeReference;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.xingda.packing.domain.Wheel;
import com.xingda.packing.enums.TaskType;
import com.xingda.packing.shunt.ticket.ShuntTicket;
import com.xingda.packing.task.ticket.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.io.*;
import java.nio.charset.StandardCharsets;
import java.util.Objects;

/**
 * 调试时使用-后续去掉
 */
@Slf4j
@Component
public class StorageUtils {
    @Value("${com.xingda.wheel.wheel1}")
    private String wheel1;
    @Value("${com.xingda.wheel.wheel2}")
    private String wheel2;
    @Value("${com.xingda.wheel.wheel3}")
    private String wheel3;
    @Value("${com.xingda.taskTicket.taskTicket1}")
    private String taskTicket1;
    @Value("${com.xingda.taskTicket.taskTicket2}")
    private String taskTicket2;
    @Value("${com.xingda.taskTicket.taskTicket3}")
    private String taskTicket3;
    @Value("${com.xingda.taskTicket.taskTicket4}")
    private String taskTicket4;

    public void saveWheel(Wheel wheel, int area) {
        try {
            String filePath;
            if (area == 1) {
                filePath = wheel1;
            } else if (area == 2){
                filePath = wheel2;
            } else {
                filePath = wheel3;
            }
            saveJson(wheel, filePath);
        } catch (Exception ex) {
            log.error("保存工字轮信息失败", ex);
        }
    }

    public Wheel loadWheel(int area) {
        try {
            String filePath;
            if (area == 1) {
                filePath = wheel1;
            } else {
                filePath = wheel2;
            }
            return readJsonFile(filePath, new TypeReference<Wheel>() {
            });
        } catch (Exception ex) {
            log.error("恢复工字轮信息失败");
        }
        return null;
    }

    public void saveTaskTicket(AbstractTaskTicket ticket, int area) {
        try {
            String filePath = null;
            if (area == 1) {
                filePath = taskTicket1;
            }
            if (area == 2) {
                filePath = taskTicket2;
            }
            if (area == 3) {
                filePath = taskTicket3;
            }
            if (area == 4) {
                filePath = taskTicket4;
            }
            saveJson(ticket, filePath);
        } catch (Exception ex) {
            log.error("保存任务状态失败", ex);
        }
    }

    public AbstractTaskTicket loadTaskTicket(int area) {
        try {
            String filePath = null;
            if (area == 1) {
                filePath = taskTicket1;
            }
            if (area == 2) {
                filePath = taskTicket2;
            }
            if (area == 3) {
                filePath = taskTicket3;
            }
            if (area == 4) {
                filePath = taskTicket4;
            }
            String readJsonStr = getReadJson(filePath);
            JSONObject json = JSONObject.parseObject(readJsonStr);
            if (Objects.nonNull(json)) {
                String typeStr = json.getString("type");
                if (Objects.nonNull(typeStr)) {
                    if (typeStr.equals(TaskType.CACHE_PALLETIZING.toString())) {
                        TypeReference<CachePackingTicket> type = new TypeReference<CachePackingTicket>() {
                        };
                        return JSONObject.parseObject(readJsonStr, type);
                    } else if (typeStr.equals(TaskType.PACKING.toString())) {
                        TypeReference<PackingTicket> type = new TypeReference<PackingTicket>() {
                        };
                        return JSONObject.parseObject(readJsonStr, type);
                    } else if (typeStr.equals(TaskType.SCANCODE.toString())) {
                        TypeReference<ScanCodeTicket> type = new TypeReference<ScanCodeTicket>() {
                        };
                        return JSONObject.parseObject(readJsonStr, type);
                    } else if (typeStr.equals(TaskType.STORAGE.toString())) {
                        TypeReference<StorageTicket> type = new TypeReference<StorageTicket>() {
                        };
                        return JSONObject.parseObject(readJsonStr, type);
                    } else if (typeStr.equals(TaskType.SHUNT.toString())) {
                        TypeReference<ShuntTicket> type = new TypeReference<ShuntTicket>() {
                        };
                        return JSONObject.parseObject(readJsonStr, type);
                    }
                }
            }
        } catch (Exception e) {
            log.error("加载任务状态失败", e);
        }
        return null;
    }

    // 将Nodes信息保存到本地json文件中
    public void saveJson(Object jsonData, String filePath) {
        String writeString = JSON.toJSONString(jsonData, SerializerFeature.PrettyFormat);
        BufferedWriter writer = null;
        File file = new File(filePath);
        // 如果文件不存在则新建
        if (!file.exists()) {
            try {
                file.createNewFile();
            } catch (IOException e) {
                log.error(e.getMessage());
            }
        }
        // 如果多次执行同一个流程，会导致json文件内容不断追加，在写入之前清空文件
        try {
            writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file, false), StandardCharsets.UTF_8));
            writer.write("");
            writer.write(writeString);
        } catch (IOException e) {
            log.error(e.getMessage());
        } finally {
            try {
                if (writer != null) {
                    writer.close();
                }
            } catch (IOException e) {
                log.error(e.getMessage());
            }
        }
    }

    // 用于读取JSON文件
    public <T> T readJsonFile(String filePath, TypeReference<T> type) {
        String readJson = getReadJson(filePath);
        // 获取json
        try {
            return JSONObject.parseObject(readJson, type);
        } catch (JSONException e) {
            log.error(e.getMessage());
        }
        return null;
    }

    private String getReadJson(String filePath) {

        BufferedReader reader = null;
        StringBuilder readJson = new StringBuilder();
        try {
            FileInputStream fileInputStream = new FileInputStream(filePath);
            InputStreamReader inputStreamReader = new InputStreamReader(fileInputStream, StandardCharsets.UTF_8);
            reader = new BufferedReader(inputStreamReader);
            String tempString;
            while ((tempString = reader.readLine()) != null) {
                readJson.append(tempString);
            }
        } catch (IOException e) {
            log.error(e.getMessage());
        } finally {
            if (reader != null) {
                try {
                    reader.close();
                } catch (IOException e) {
                    log.error(e.getMessage());
                }
            }
        }
        return readJson.toString();
    }
}
